//分辨率640*480

//H Sync_Time	H Bach Porch	H Left Border	H Data Time		H Right Border		H Front Porch
//		96				  40			      8				 640					 8						8		
//V Sync_Time	V Bach Porch	V Top Border 	V Data Time		V Bottom Border	V Front Porch
//		2				  25			      8				 480					 8						2

module VGA_CTRL(
	clk25m		,
	rst_n			,
	data_in  	,	//待显示的数据
	hcount		,
	vcount		,
	VGA_RGB		,
	VGA_HS		,
	VGA_VS		,
	VGA_BLK		,
	VGA_CLK	
);

	input							clk25m	;									
	input							rst_n		;				
	input				[23:0]	data_in	;		  	
	output			[9:0]		hcount	;				
	output			[9:0]		vcount	;			
	output			[23:0]	VGA_RGB	;			
	output						VGA_HS	;			
	output						VGA_VS	;			
	output						VGA_BLK	;		
   output   					VGA_CLK	;	

	parameter	VGA_HS_end 	= 10'd95	,	//H Sync_Time - 1	
					hdat_begin 	= 10'd143,	//H Sync_Time+H Bach Porch+H Left Border - 1 
					hdat_end		= 10'd783,	//H Sync_Time+H Bach Porch+H Left Border+H Data Time - 1
					hpixel_end	= 10'd799,  //hdat_end + H Right Border+H Front Porch - 1
					VGA_VS_end	= 10'd1	,	//V Sync_Time - 1	
					vdat_begin	= 10'd34	,	//V Sync_Time+V Bach Porch+V Top Border - 1
					vdat_end		= 10'd514,  //vdat_begin + V Data Time - 1
					vline_end	= 10'd524;	//vdat_end + V Bottom Border + V Front Porch - 1
			
	reg [9:0]hcount_r,vcount_r;
	
	wire hcount_ov,vcount_ov;
	wire dat_act; 	//有效显示标志
	
	assign VGA_CLK = ~clk25m;//将VGA控制器时钟信号取反输出，作为DAC数据锁存信号（VGA是模拟信号驱动）
	assign hcount_ov = (hcount_r == hpixel_end)?1'b1:1'b0;
	assign vcount_ov = (vcount_r == vline_end )?1'b1:1'b0;
	assign dat_act = ((hcount_r >= hdat_begin) && (hcount_r < hdat_end) && 
						  (vcount_r >= vdat_begin) && (vdat_begin < vdat_end))?1'b1:1'b0;
	assign hcount  = dat_act ? (hcount_r - hdat_begin) : 10'd0;
	assign vcount  = dat_act ? (vcount_r - vdat_begin) : 10'd0;
	assign VGA_BLK = dat_act;
	assign VGA_HS = (hcount_r > VGA_HS_end)?1'b1:1'b0;
	assign VGA_VS = (vcount_r > VGA_VS_end)?1'b1:1'b0;
	assign VGA_RGB = (dat_act) ? data_in : 24'h000000;
	
	always @ (posedge clk25m or negedge rst_n)
	if (!rst_n)
		hcount_r <= 10'd0;
	else if (hcount_ov)
		hcount_r <= 10'd0;
	else
		hcount_r <= hcount_r + 1'b1;
		
	always @ (posedge clk25m or negedge rst_n)
	if (!rst_n)
		vcount_r <= 10'd0;
	else if (hcount_ov)
		begin
			if (vcount_ov)
				vcount_r <= 10'd0;
			else
				vcount_r <= vcount_r + 1'b1;
		end
	else
		vcount_r <= vcount_r;

endmodule 